package com.demo.dune.base;

import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import lombok.extern.slf4j.Slf4j;

/**
 * GlobalExceptionHandler.
 * @author Allen
 * @version 1.0 2022-04-04
 */
@Slf4j
@ResponseBody 
@ControllerAdvice
public class GlobalExceptionHandler {

	/**
	 * handle MethodArgumentNotValidException.
	 * @param validException
	 * @return ResultVO
	 */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public ResultVO paramExceptionHandler(MethodArgumentNotValidException validException) {
    	log.info("MethodArgumentNotValidException occur, go into paramExceptionHandler");
        BindingResult exceptions = validException.getBindingResult();
        // Judge whether there is error information in the exception. 
        // If there is, use the message in the exception; otherwise, use the default message
        if (exceptions != null && exceptions.hasErrors()) {
            List<ObjectError> errors = exceptions.getAllErrors();
            if (!errors.isEmpty()) {
                FieldError fieldError = (FieldError) errors.get(0);
                return new ResultVO(ResultCodeEnum.DATACHECK_ERROR.getCode(), 
                		fieldError.getDefaultMessage());
            }
        }
        return new ResultVO(ResultCodeEnum.DATACHECK_ERROR);
    }
    
    /**
     * handle ServiceErrorException.
     * @param errorException
     * @return ResultVO
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({ServiceErrorException.class})
    public ResultVO serviceExceptionHandler(ServiceErrorException errorException) {
    	log.info("ServiceErrorException occur, go into serviceExceptionHandler");
        if (StringUtils.isNotEmpty(errorException.getMessage())) {
            return new ResultVO(ResultCodeEnum.SERVICE_ERROR.getCode(), errorException.getMessage());
        }
        return new ResultVO(ResultCodeEnum.SERVICE_ERROR);
    }
 
    /**
     * handle HttpMessageNotReadableException.
     * @param httpException
     * @return ResultVO
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResultVO parameterBodyMissingExceptionHandler(HttpMessageNotReadableException httpException) {
    	log.info("HttpMessageNotReadableException occur, go into parameterBodyMissingExceptionHandler");
        // when input json is empty
        return new ResultVO(ResultCodeEnum.EMPTY_INPUT_ERROR);
    }
    
}
